package ua.ad.consumer;

import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.ibatis.session.SqlSession;

import ua.ad.feedsreader.mybatis.config.MyBatisSqlSessionFactory;
import ua.ad.feedsreader.mybatis.mappers.beans.Feed;
import ua.ad.feedsreader.mybatis.mappers.beans.ItemFeed;
import ua.ad.feedsreader.mybatis.mappers.clients.FeedMapper;
import ua.ad.feedsreader.mybatis.mappers.clients.ItemFeedMapper;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

/**
 * 
 * @author ricardo
 *
 */
public class FeedsManager {

	private static final Logger LOGGER = Logger.getLogger(SchedulerManager.class.getName());

	private SqlSession bdSession;

	public FeedsManager() {
		this.bdSession = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
	}

	public void addItems(Feed feed, SyndEntry entry ) {
		
		ItemFeedMapper itemFeedMapper = bdSession.getMapper(ItemFeedMapper.class);
		//verifica se o item feed ja existe na tabela
		ItemFeed selectByFeedId = itemFeedMapper.selectByUrl( entry.getLink() );
		if( selectByFeedId == null ) {
			
			LOGGER.log(Level.INFO, "From:"+ feed.getUrl() + " new entry:" + entry.getTitle() );
			
			selectByFeedId = new ItemFeed();
			String totalString = entry.getDescription().getValue();
			selectByFeedId.setDescricao( totalString.length() > 4000 ? totalString.substring(0, 4000) : totalString );
			selectByFeedId.setTitulo( entry.getTitle() );
			selectByFeedId.setIdFeed( feed.getId() );
			selectByFeedId.setUrl( entry.getLink() );
			selectByFeedId.setDataPublicacao( entry.getPublishedDate() );
			itemFeedMapper.insertSelective(selectByFeedId);
		}
		
	}
	
	/**
	 * permite a chamada do loader de feeds para uma feed especifica através do seu ID.
	 * @param id identificador da feed
	 * @return 
	 */
	public Integer loadFeed( Integer id ) {
		XmlReader reader = null;
		FeedMapper feedMapper = bdSession.getMapper(FeedMapper.class);
		Feed feed = feedMapper.selectByPrimaryKey(id);
		try {
			
			URL url = new URL( feed.getUrl() );
			reader = new XmlReader( url );
			SyndFeed feedItem = new SyndFeedInput().build( reader );

			// guardar o titulo da Feed
			feed.setDescricao( feedItem.getTitle() );
			feedMapper.updateByPrimaryKey(feed);
			
			for ( Iterator<?> i = feedItem.getEntries().iterator(); i.hasNext(); ) {
				addItems(feed, (SyndEntry) i.next() );
			}
			return id;
			
		} catch (Exception e) {
			//LOGGER.log(Level.SEVERE, "From loadFeed:"+ e.getMessage() );
			e.printStackTrace();
		}
		return null;
	}
	
	public void loadFeed( Feed feed ) {
		XmlReader reader = null;
		URL url = null;
		SyndFeed feedItem = null;
		try {
			url = new URL( feed.getUrl() );
			reader = new XmlReader( url );
			feedItem = new SyndFeedInput().build( reader );
			
			for ( Iterator<?> i = feedItem.getEntries().iterator(); i.hasNext(); ) {
				addItems(feed, (SyndEntry) i.next() );
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			reader = null;
			url = null;
			feedItem = null;
		}
	}

	public void loadAllFeeds() {
		//ler todas as feeds;
		FeedMapper feedMapper = bdSession.getMapper(FeedMapper.class);
		List<Feed> listaFeeds = feedMapper.selectAllFeeds();

		LOGGER.log(Level.INFO, "List of Feeds:" + listaFeeds.size() );

		for (Feed feed : listaFeeds) {
			loadFeed(feed);
		}
	}

	public void commitAndCloseConnection() {
		bdSession.commit();
		bdSession.close();
	}

}
